package com.bruce.apkinstaller;

import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;

import com.bruce.apkinstaller.install.AbstractFactory;
import com.bruce.apkinstaller.install.FactoryProducer;
import com.bruce.apkinstaller.install.InstallStatusCallback;
import com.bruce.apkinstaller.install.ProductArgsInstallImpl;
import com.bruce.apkinstaller.install.ProductPmInstallImpl;
import com.bruce.apkinstaller.other.ParseApk;
import com.htrip.toolsmodule.L;
import com.htrip.toolsmodule.ToastUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2018/1/19.
 */

public class InstallService extends BaseService implements InstallStatusCallback {
    private static final String TAG = InstallService.class.getSimpleName();
    private Map<String, Object> apkInfo = new HashMap<>();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        initStart(intent);
        return super.onStartCommand(intent, flags, startId);
    }

    private void initStart(Intent intent) {
        apkList = intent.getStringArrayListExtra(Receiver.ACTION_APK_LIST);
        installType = intent.getBooleanExtra(Receiver.ACTION_INSTALL_TYPE, true);
        installOrUninstall = intent.getBooleanExtra(Receiver.ACTION_OPTION_TYPE, true);
        L.d(TAG, "apk install list: " + apkList.toString() + "\n installType: " + installType + "\ninstallOrUninstall: " + installOrUninstall);
        finishedCount = 0;
        mContext = this;
        ToastUtil.show(mContext, "升级应用中：" + apkList.size(), 3000);
        if (isInstallTaskRunning) {
            isInstallTaskRunning = false;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    startInstall(apkList);
                }
            }).start();
        } else {
            Log.d(TAG, "应用升级正在执行中...");
        }
    }

    private void startInstall(ArrayList<String> appUpdateList) {
        AbstractFactory installFactory = FactoryProducer.getFactory(installOrUninstall);
        if (installOrUninstall) {
            if (installType) {
                pmBatchInstall(appUpdateList, installFactory);
            } else {
                argsBatchInstall(appUpdateList, installFactory);
            }
        }
    }

    /**
     * 调用系统安装方式安装多个应用
     *
     * @param appUpdateList
     * @param installFactory
     */

    private void pmBatchInstall(ArrayList<String> appUpdateList, AbstractFactory installFactory) {
        ProductPmInstallImpl pmInstall = (ProductPmInstallImpl) installFactory.getInstallType(true); //从工厂中获取安装类型
        pmInstall.setInstallCallback(appUpdateList, this);
        pmInstall.start();
    }

    /**
     * 调用命令行安装方式安装多个应用
     *
     * @param appUpdateList
     * @param installFactory
     */
    private void argsBatchInstall(ArrayList<String> appUpdateList, AbstractFactory installFactory) {
        ProductArgsInstallImpl argsInstall = (ProductArgsInstallImpl) installFactory.getInstallType(false);//从工厂中获取安装类型
        argsInstall.setInstallCallback(appUpdateList, this);
        argsInstall.start();
    }

    private void count() {
        Log.d(TAG, "count()： " + finishedCount);
        finishedCount++;
        if (finishedCount == apkList.size() - 1) {
            isInstallTaskRunning = true;
        }
        if (finishedCount == apkList.size()) {
            isInstallTaskRunning = true;
        }
    }

    @Override
    protected void release() {
        Log.d(TAG, "release()");
    }

    @Override
    public void failure(String app, Object reason) {
        count();
        Log.e(TAG, "安装失败：" + app + "\n失败原因：" + reason);
    }

    @Override
    public void success(String app) {
        count();
        Log.d(TAG, "安装成功：" + app);
    }

    @Override
    public void progress(String app, int progress) {
        sendProgress(app, progress);
    }

    private void sendProgress(String app, int progress) {
        Message msg = new Message();
        Bundle bundle = new Bundle();
        bundle.putInt(PROGRESS, progress);
        bundle.putString(NAME, app);
        msg.what = MSG_PROGRESS;
        msg.setData(bundle);
        mHandler.sendMessage(msg);
    }

    @Override
    protected void handleMsg(Message msg) {
        switch (msg.what) {
            case MSG_PROGRESS:
                Log.d(TAG, "安装进度：" + msg.getData().getInt(PROGRESS) + "\n 应用:" + msg.getData().getString(NAME));
                initDialog(msg.getData().getString(NAME), msg.getData().getInt(PROGRESS));
                if (msg.getData().getInt(PROGRESS) == 100) {
                    ToastUtil.show(mContext, "升级完成！", 3000);
                    dialog.dismiss();
                    stopSelf();
                }
                break;
        }
    }

    private void initDialog(String packageName, int progress) {
        if (dialog == null) {
            view = View.inflate(this, R.layout.update_dialog, null);
            updatedialogContent = view.findViewById(R.id.dialog_content);
            mHorizonalProgress = view.findViewById(R.id.progressBar2);
            builder = new AlertDialog.Builder(this);
            builder.setView(view);
            dialog = builder.create();
            dialog.setCanceledOnTouchOutside(false);
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); //系统中关机对话框就是这个属性
//            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);  //窗口可以获得焦点，响应操作
            //d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY);  //窗口不可以获得焦点，点击时响应窗口后面的界面点击事件
        }
        apkInfo = ParseApk.getApkInfo(mContext, apkList.get(finishedCount - 1));
        mHorizonalProgress.setProgress(progress);
        updatedialogContent.setText(
                "Package:" + packageName +
                        "\nVersion：" + apkInfo.get(ParseApk.ApkInfos.VE_NAME) +
                        "\nVersionCode: " + apkInfo.get(ParseApk.ApkInfos.VE_CODE) +
                        "\nUpgrading: " + finishedCount +
                        "\nNeed to upgrade: " + apkList.size());
        dialog.show();
    }
}
